﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
using Client;
using System;
using System.Text.RegularExpressions;
using UnityEditor.Experimental.SceneManagement;

public class GenUIVisualTool
{
    [MenuItem("GameObject/程序工具/UI/填充UIVisual", false, -1)]
    private static void Gen()
    {
        var visual = SearchUIVisual(Selection.activeGameObject.transform);
        if (visual == null)
        {
            EditorUtility.DisplayDialog("异常", "未找到UIVisial组件，请给预制添加UIVisual组件", "确定");
            return;
        }

        FillUIVisual(visual);
    }

    /// <summary>
    /// 查找UIVisual
    /// </summary>
    /// <param name="trans"></param>
    /// <returns></returns>
    private static UIVisual SearchUIVisual(Transform trans)
    {
        UIVisual visual = null;
        while (trans != null)
        {
            visual = trans.GetComponent<UIVisual>();
            if (visual != null)
            {
                break;
            }
            if (trans.parent == null)
            {
                break;
            }
            trans = trans.parent;
        }
        return visual;
    }

    /// <summary>
    /// 为选定UI预制填充UIVisual
    /// </summary>
    /// <param name="visual"></param>
    private static void FillUIVisual(UIVisual visual)
    {
        visual.Paths.Clear();
        visual.GameObjects.Clear();
        AddNamedNode(visual, visual.transform);
        if (!AddAnchorNode(visual))
        {
            return;
        }
        AddCanvas(visual);
        AddGraphicRaycaster(visual);

        if (PrefabUtility.GetPrefabAssetType(visual.gameObject) != PrefabAssetType.NotAPrefab)
        {
            PrefabUtility.ApplyPrefabInstance(visual.gameObject, InteractionMode.AutomatedAction);
        }
        else
        {
            var path = PrefabStageUtility.GetCurrentPrefabStage().prefabAssetPath;
            PrefabUtility.SaveAsPrefabAsset(visual.gameObject, path);
        }

        EditorUtility.DisplayDialog("完成", "UIVisual数据填充完成", "确定");
    }

    /// <summary>
    /// 记录特殊的命名节点
    /// </summary>
    /// <param name="visual"></param>
    /// <param name="trans"></param>
    private static void AddNamedNode(UIVisual visual, Transform trans)
    {
        if (trans != visual.transform)
        {
            if (trans.name.EndsWith(".GO", StringComparison.OrdinalIgnoreCase))
            {
                string path = UIHelper.GetTransformRelativePath(trans, visual.transform);
                visual.Paths.Add(path);
                visual.GameObjects.Add(trans.gameObject);
            }
        }

        for (int i = 0; i < trans.childCount; i++)
        {
            AddNamedNode(visual, trans.GetChild(i));
        }
    }

    /// <summary>
    /// 记录边缘锚点
    /// </summary>
    /// <param name="visual"></param>
    /// <returns></returns>
    private static bool AddAnchorNode(UIVisual visual)
    {
        visual.Anchors = new List<Transform>
        {
            visual.transform.Find("Animation/TopLeft"),
            visual.transform.Find("Animation/Top"),
            visual.transform.Find("Animation/TopRight"),
            visual.transform.Find("Animation/Left"),
            visual.transform.Find("Animation/Center"),
            visual.transform.Find("Animation/Right"),
            visual.transform.Find("Animation/BottomLeft"),
            visual.transform.Find("Animation/Bottom"),
            visual.transform.Find("Animation/BottomRight"),
        };

        for (int i = 0; i < visual.Anchors.Count; ++i)
        {
            var trans = visual.Anchors[i];
            if (trans == null)
            {
                EditorUtility.DisplayDialog("异常", string.Format("找不到{0}锚点", (UIVisual.EAnchor)(i)), "确定");
                return false;
            }
        }
        return true;
    }

    /// <summary>
    /// Canvas
    /// </summary>
    /// <param name="visual"></param>
    private static void AddCanvas(UIVisual visual)
    {
        var canvas = visual.GetComponent<Canvas>();
        if (canvas == null)
        {
            canvas = visual.gameObject.AddComponent<Canvas>();
        }

        canvas.renderMode = RenderMode.WorldSpace;
        visual.Canvas = canvas;
    }

    /// <summary>
    /// GraphicRaycaster
    /// </summary>
    /// <param name="visual"></param>
    private static void AddGraphicRaycaster(UIVisual visual)
    {
        var raycaster = visual.GetComponent<GraphicRaycaster>();
        if (raycaster == null)
        {
            raycaster = visual.gameObject.AddComponent<GraphicRaycaster>();
        }
        raycaster.ignoreReversedGraphics = true;
        raycaster.blockingObjects = GraphicRaycaster.BlockingObjects.All;
        visual.GraphicRaycaster = raycaster;
    }
}
